﻿using Colorful.Furniture.CommonDto;
using Colorful.Furniture.Enum;
using Colorful.Furniture.ErpCustomerManagement;
using Colorful.Furniture.ErpOrderManagement;
using Colorful.Furniture.Extensions;
using Colorful.Furniture.InterfaceUpstream;
using Colorful.Furniture.SysManagement;
using Colorful.Furniture.Wrappers;
using FreeSql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Auditing;
using Volo.Abp.Guids;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Users;

namespace Colorful.Furniture.ErpSupplierManagement;

/// <summary>
/// 供应商服务
/// </summary>
[Authorize]
public class SupplierAppService : ApplicationService
{
    private readonly IBaseRepository<Supplier> _supplierRepository;
    private readonly IBaseRepository<SupplierBalanceLog> _supplierBalanceLogRepository;
    private readonly IBaseRepository<SupplierLog> _supplierLogRepository;
    private readonly IGuidGenerator _guidGenerator;
    private readonly IFreeSql _freeSql;
    private readonly IObjectMapper _objectMapper;
    private readonly CurrentUser _currentUser;
    public SupplierAppService(
        IBaseRepository<Supplier> supplierRepository,
        IBaseRepository<SupplierBalanceLog> supplierBalanceLogRepository,
        IBaseRepository<SupplierLog> supplierLogRepository,
        IGuidGenerator guidGenerator,
        IFreeSql freeSql,
        IObjectMapper objectMapper,
        CurrentUser currentUser)
    {
        _supplierRepository = supplierRepository;
        _supplierBalanceLogRepository = supplierBalanceLogRepository;
        _supplierLogRepository = supplierLogRepository;
        _guidGenerator = guidGenerator;
        _freeSql = freeSql;
        _objectMapper = objectMapper;
        _currentUser = currentUser;
    }


    /// <summary>
    ///  分页
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<PageResponseWrapper<List<SupplierPagedOutputDto>>> PostPagedAsync([FromBody] SupplierPagedInputDto input)
    {

        var query = _freeSql.Select<Supplier, SysDictionary>()
            .LeftJoin((x, y) => x.Type == y.Id)
            .Where((x, y) => !x.IsDeleted)
            .WhereIf(!string.IsNullOrWhiteSpace(input.Keyword), (x, y) => x.Name.Contains(input.Keyword.Trim()) || x.Code.ToString().Contains(input.Keyword.Trim()))
            .WhereIf(input.Status != null, (x, y) => x.Status == input.Status)
            .DisableGlobalFilter("SoftDelete");

        var sumItem = await query
            .ToAggregateAsync((x, y) => new
            {
                SumBalance = x.Sum(x.Key.Balance)
            });

        var list = await query
            .OrderByDescending((x, y) => x.Sort)
            .OrderByDescending((x, y) => x.AddTime) //按照创建时间倒序
            .OrderByDescending((x, y) => x.Status) //按照启用禁用倒序
            .Count(out var pageTotalCount)
            .Page(input.PageIndex, input.PageSize)
            .ToListAsync(x => new SupplierPagedOutputDto());
        
        return new PageResponseWrapper<List<SupplierPagedOutputDto>, object>
        {
            Total = pageTotalCount,
            Items = list,
            SumItems = new { sumItem.SumBalance }
        };

    }


    /// <summary>
    ///  获取详情
    /// </summary>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<SupplierDetailOutputDto> GetDetailAsync(Guid id)
    {
        var model = await _supplierRepository
            .Where(x => x.Id == id)
            .ToOneAsync(x => new SupplierDetailOutputDto());

        return model;
    }


    /// <summary>
    ///  批量逻辑删除
    /// </summary>
    /// <param name="idList">ID集合</param>
    /// <returns></returns> 
    public async Task<bool> DeleteBatchByIdAsync([FromBody] List<Guid?> idList)
    {
        await _freeSql.Update<Supplier>()
            .Set(x => x.IsDeleted, true)
            .Set(x => x.DeletedTime, DateTime.Now)
            .Where(x => idList.Contains(x.Id))
            .ExecuteAffrowsAsync();

        return true;
    }

    
    /// <summary>
    ///  保存供应商信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<Guid?> SaveAsync([FromBody] SaveSupplierInputDto input)
    {
        //修改
        if (!input.Id.IsNull())
        {
            var supplierInfo = _freeSql.Select<Supplier>()
                .Where(x => x.Id == input.Id).ToOne();
            if (supplierInfo == null)
                throw new UserFriendlyException("供应商信息不存在，请联系管理员！");

            // 日志记录
            var supplierLogUpdateInfo = new SupplierLog()
            {
                SupplierId = input.Id,
                ChangePrice = 0,
                BeforePrice = supplierInfo.Price,
                AfterPrice = input.Price,
                BeforeCreditPrice = supplierInfo.CreditPrice,
                AfterCreditPrice = input.CreditPrice,
                Operator = CurrentUser.Name,
                OperatorNo = CurrentUser.UserName,
                OperatorType = !input.Id.HasValue ? EnumOperatorType.新增 : EnumOperatorType.修改,
                OperatorTime = Clock.Now,
                LogContent = $"【{CurrentUser.Name}】执行【修改】客户信息 - 供应商名称：【{supplierInfo.Name}】 ；供应商编码：【{supplierInfo.Code}】 ；" +
                             $"账户余额：{supplierInfo.Price} → {input.Price} ；授信额度：{supplierInfo.CreditPrice} → {input.CreditPrice}",
                RequestJson = JsonConvert.SerializeObject(input, Formatting.None),
            };

            var suppliers = _objectMapper.Map(input, supplierInfo);

            await _freeSql.Update<Supplier>()
                .SetSource(suppliers)
                .ExecuteAffrowsAsync();

            await _supplierLogRepository.InsertAsync(supplierLogUpdateInfo);

            return input.Id;
        }

        //新增
        var supplierInsert = _objectMapper.Map<SaveSupplierInputDto, Supplier>(input);
        var code = SetSupplierCode();
        supplierInsert.Balance = 0;
        supplierInsert.Price = 0;
        supplierInsert.Code = code;
        supplierInsert.AddTime = DateTime.Now;
        supplierInsert.Status = 1;
        supplierInsert.AddUserId = _currentUser.Id;
        await _freeSql
        .Insert(supplierInsert)
            .ExecuteAffrowsAsync();
        
        return supplierInsert.Id;
    }
    

    /// <summary>
    /// 生成客户编号
    /// </summary>
    [RemoteService(false)]
    public int SetSupplierCode()
    {
        //获得当前最大编号
        var orderInfo = _freeSql.Select<Supplier>()
            .DisableGlobalFilter("SoftDelete")
            .OrderByDescending(x => x.AddTime)
            .FirstAsync();

        var number = 101;
        if (orderInfo.Result != null)
        {
            number = Convert.ToInt32(orderInfo.Result.Code) + 1;
        }
        return number;
    }


}

